<?php

/**
 * This file is part of ossecdb-extjs.
 * 
 * Copyright (C) 2011 Brendan Johnston
 * 
 * Contact: brendan@johnston.net.au
 * 
 * Project: http://code.google.com/p/ossecdb-extjs/
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

require('_inc/_all.php');

//:~

$ext = (object) array(
	'sort' => (object) array(
		'direction' => array(
			'ASC' => 'ASC', 
			'DESC' => 'DESC'
		)
	),
	'filter' => (object) array(
		'comparison' => array(
			'lt' => '<',
			'eq' => '=',
			'gt' => '>'
		)
	)
);

//:~

try 
{
	$req = (object) array();

	$req->safe_start = intval($_REQUEST['start']);
	$req->safe_limit = intval($_REQUEST['limit']);

	$req->safe_sort = array(
		(object) array(
			'property' => $queries->alert_key,
			'direction' => 'DESC'
		)	
	);

	if (isset($_REQUEST['sort']))
	{
		$temp = (object) array(
			'sent_sort' => json_decode($_REQUEST['sort']),
			'safe_sort' => array(),
			'default' => true
		);

		if (is_array($temp->sent_sort))
		{
			foreach ($temp->sent_sort as $sort)
			{
				if (is_object($sort))
				{
					if ($queries->alert_col[$sort->property] && $ext->sort->direction[$sort->direction])
					{
						if ($sort->property == $queries->alert_key)
						{
							$temp->default = false;
						}

						$temp->safe_sort[] = $sort;
					}
				}
			}
		}

		if ($temp->default)
		{
			$temp->safe_sort[] = (object) array(
				'property' => $queries->alert_key,
				'direction' => 'DESC'
			);
		}

		$req->safe_sort = $temp->safe_sort;

		unset($temp);
	}

	//:~

	$clause = array();

	//:~

	if (isset($_REQUEST['loc_filter']))
	{
		$loc_filter = (object) array(
			'sent' => json_decode($_REQUEST['loc_filter']),
			'host_in' => array(),
			'host_or' => array()
		);

		foreach ($loc_filter->sent as $loc)
		{
			if (isset($loc->user) || isset($loc->path))
			{
				$host_or = $queries->alert_col['loc_host'] . " = " . ossec_db::db()->quote($loc->host);

				if (isset($loc->user))
				{
					$host_or .= ' and ' . $queries->alert_col['user'] . ' in (' . implode(', ', array_map('ossec_db_quote', $loc->user)) . ')';
				}

				if (isset($loc->path))
				{
					$host_or .= ' and ' . $queries->alert_col['loc_path'] . ' in (' . implode(', ', array_map('ossec_db_quote', $loc->path)) . ')';
				}

				$host_or = "($host_or)";

				$loc_filter->host_or[] = $host_or;
			}
			else
			{
				$loc_filter->host_in[] = ossec_db::db()->quote($loc->host);
			}
		}
		
		$loc_filter->clause = array();

		if (count($loc_filter->host_in))
		{
			$loc_filter->clause[] = $queries->alert_col['loc_host'] . ' in (' . implode($loc_filter->host_in) . ')';
		}

		if (count($loc_filter->host_or))
		{
			$loc_filter->clause[] = implode(' or ', $loc_filter->host_or);
		}

		// if sent empty filters clause (loc_filter=[]), 1=0 causes nothing to be returned
		if (count($loc_filter->clause) == 0)
		{
			$loc_filter->clause[] = '1=0';
		}

		if (count($loc_filter->clause))
		{
			$clause[] = '(' . implode(' or ', $loc_filter->clause) . ')';
		}
	}

	//:~

	$req->sent_filter = array();

	if (isset($_REQUEST['filter']))
	{
		$req->sent_filter = json_decode($_REQUEST['filter']);
	}

	if (is_array($req->sent_filter))
	{
		foreach ($req->sent_filter as $filter)
		{
			if (is_object($filter))
			{
				if ($queries->alert_col[$filter->field])
				{
					if (method_exists('ossec_filter', $filter->field))
					{
						$clause[] = call_user_func(array('ossec_filter', $filter->field), $filter);
					} 
					else if ($filter->type == 'date')
					{
						if ($operator = $ext->filter->comparison[$filter->comparison])
						{
							$clause[] = $queries->alert_col[$filter->field] . ' ' . $operator . ' ' . strtotime($filter->value);
						}
					}
					else if ($filter->type == 'list')
					{
						$clause[] = $queries->alert_col[$filter->field] . ' in (' . implode(', ', array_map('ossec_db_quote', $filter->value)) . ')';
					}
					else if ($filter->type == 'numeric')
					{
						if ($operator = $ext->filter->comparison[$filter->comparison])
						{
							$clause[] = $queries->alert_col[$filter->field] . ' ' . $operator . ' ' . floatval($filter->value);
						}
					}
					else if ($filter->type == 'string')
					{
						$clause[] = $queries->alert_col[$filter->field] . ' like ' . ossec_db::db()->quote('%' . $filter->value . '%');
					}
				}
			}
		}
	}

	//:~

	$tsql = 'select count(*) as total from ' . $queries->alert_from . ' ';

	if (count($clause))
	{
		$tsql .= 'where ' . implode(' and ', $clause) . ' ';
	}

	//:~

	$dsql = $queries->alert;

	if (count($clause))
	{
		$dsql .= 'where ' . implode(' and ', $clause) . ' ';
	}

	if (count($req->safe_sort))
	{
		$clause = array();

		foreach ($req->safe_sort as $sort)
		{
			$clause[] = $queries->alert_col[$sort->property] . ' ' . $sort->direction;
		}

		$dsql .= 'order by ' . implode(', ', $clause) . ' ';

		unset($clause);
	}

	//:~

	if ($req->safe_limit)
	{
		$dsql .= 'limit ' . $req->safe_limit . ' offset ' . $req->safe_start;
	}

	//:~

	echo json_encode(
		ossec_db::result($tsql, $dsql, true)	
	);

	ossec_db::close();
} 
catch (PDOException $e)
{
	echo 'Error connecting to DB!: '.$e->getMessage();
	exit();
}